package com.san.common.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 日期处理
 */
public class DateUtils {
	private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);
	/**
	 * 时间格式(yyyy-MM-dd)
	 */
	public final static String DATE_PATTERN = "yyyy-MM-dd";
	/**
	 * 时间格式(yyyy-MM-dd HH:mm:ss)
	 */
	public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

	public static final Map<Integer, Character> charMap = new HashMap<Integer, Character>();
	public static final Pattern p = Pattern.compile("^(\\d+)\\D*(\\d*)\\D*(\\d*)\\D*(\\d*)\\D*(\\d*)\\D*(\\d*)");

	static {
		charMap.put(1, 'y');
		charMap.put(2, 'M');
		charMap.put(3, 'd');
		charMap.put(4, 'H');
		charMap.put(5, 'm');
		charMap.put(6, 's');
	}

	public static String format(Date date) {
		return format(date, DATE_PATTERN);
	}

	public static String format(Date date, String pattern) {
		if (date != null) {
			SimpleDateFormat df = new SimpleDateFormat(pattern);
			return df.format(date);
		}
		return null;
	}

	/**
	 * 字符串转时间
	 * 
	 * @param strDate 默认格式为yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static Date parse(String strDate) {
		Date date = null;
		SimpleDateFormat df = new SimpleDateFormat(DATE_TIME_PATTERN);
		try {
			date = df.parse(strDate);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 字符串转时间
	 * 
	 * @param strDate
	 * @param pattern
	 * @return
	 */
	public static Date parse(String strDate, String pattern) {
		Date date = null;
		SimpleDateFormat df = new SimpleDateFormat(pattern);
		try {
			date = df.parse(strDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 计算距离现在多久，非精确
	 *
	 * @param date
	 * @return
	 */
	public static String getTimeBefore(Date date) {
		Date now = new Date();
		long l = now.getTime() - date.getTime();
		long day = l / (24 * 60 * 60 * 1000);
		long hour = (l / (60 * 60 * 1000) - day * 24);
		long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
		long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
		String r = "";
		if (day > 0) {
			r += day + "天";
		} else if (hour > 0) {
			r += hour + "小时";
		} else if (min > 0) {
			r += min + "分";
		} else if (s > 0) {
			r += s + "秒";
		}
		r += "前";
		return r;
	}

	/**
	 * 计算距离现在多久，精确
	 *
	 * @param date
	 * @return
	 */
	public static String getTimeBeforeAccurate(Date date) {
		Date now = new Date();
		long l = now.getTime() - date.getTime();
		long day = l / (24 * 60 * 60 * 1000);
		long hour = (l / (60 * 60 * 1000) - day * 24);
		long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
		long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
		String r = "";
		if (day > 0) {
			r += day + "天";
		}
		if (hour > 0) {
			r += hour + "小时";
		}
		if (min > 0) {
			r += min + "分";
		}
		if (s > 0) {
			r += s + "秒";
		}
		r += "前";
		return r;
	}

	/**
	 * 获取当前时间
	 * 
	 * @return
	 */
	public static String getNow() {
		return format(new Date(), "yyyyMMddHHmmssSSS");
	}

	/**
	 * 获取昨天时间
	 * 
	 * @param farmat 格式
	 * @return
	 */
	public static String getYesterday(String format) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1);

		SimpleDateFormat df = new SimpleDateFormat(format);

		String yesterday = df.format(calendar.getTime());

		return yesterday;
	}

	/**
	 * 通过时间秒毫秒数判断两个时间的间隔天数
	 * 
	 * @param date1
	 * @param date2 被减时间
	 * @return
	 */
	public static int differentDaysByMillisecond(Date date1, Date date2) {
		int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
		return days;
	}

	/**
	 * 通过时间秒毫秒数判断两个时间的间隔毫秒数
	 * 
	 * @param date1
	 * @param date2 被减时间
	 * @return
	 */
	public static long differentMillisecond(Date date1, Date date2) {
		long time = date2.getTime() - date1.getTime();
		return time;
	}

	/**
	 * 任意日期字符串转换为Date，不包括无分割的纯数字（13位时间戳除外） ，日期时间为数字，年月日时分秒，但没有毫秒
	 * 
	 * @param dateString 日期字符串
	 * @return Date
	 */
	public static Date stringToDate(String dateString) throws Exception{
		dateString = dateString.trim().replaceAll("[a-zA-Z]", " ");
		if (Pattern.matches("^[-+]?\\d{13}$", dateString)) {// 支持13位时间戳
			return new Date(Long.parseLong(dateString));
		}
		Matcher m = p.matcher(dateString);
		StringBuilder sb = new StringBuilder(dateString);
		if (m.find(0)) {// 从被匹配的字符串中，充index = 0的下表开始查找能够匹配pattern的子字符串。m.matches()的意思是尝试将整个区域与模式匹配，不一样。
			int count = m.groupCount();
			for (int i = 1; i <= count; i++) {
				for (Map.Entry<Integer, Character> entry : charMap.entrySet()) {
					if (entry.getKey() == i) {
						sb.replace(m.start(i), m.end(i), replaceEachChar(m.group(i), entry.getValue()));
					}
				}
			}
		} else {
			throw new Exception("错误的日期格式");
		}
		String format = sb.toString();
		SimpleDateFormat sf = new SimpleDateFormat(format);
		try {
			return sf.parse(dateString);
		} catch (ParseException e) {
			throw new Exception("错误的日期格式");
		}
	}

	/**
	 * 将指定字符串的所有字符替换成指定字符，跳过空白字符
	 * 
	 * @param s 被替换字符串
	 * @param c 字符
	 * @return 新字符串
	 */
	public static String replaceEachChar(String s, Character c) {
		StringBuilder sb = new StringBuilder("");
		for (Character c1 : s.toCharArray()) {
			if (c1 != ' ') {
				sb.append(String.valueOf(c));
			}
		}
		return sb.toString();
	}
	
	/**
	 * 获取unix精确到秒的当前时间戳
	 * @return
	 */
	public static String getUnixTimespan() {
		String now = format(new Date(),DATE_TIME_PATTERN);
		Date date = parse(now,DATE_TIME_PATTERN);
		return String.valueOf(date.getTime() / 1000);
	}

}
